home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / Assembly / FastFind.a < prev    next >
Text File  |  1994-08-04  |  6KB  |  352 lines

  1.     STRING ASIS
  2.     
  3. Debug:        set    0
  4. LinkAll:    set    1
  5.  
  6.     LOAD    'ProgStrucMacs.d'
  7.     LOAD    'FlowCtlMacs.d'
  8.  
  9. findRecord    record    0
  10. size    ds.l    1
  11. datap    ds.l    1
  12. word    ds.b    64
  13. rn    ds.w    1
  14. filelen    ds.l    1
  15. pos    ds.l    1
  16. count    ds.l    1
  17. di    ds.l    1
  18. skip    ds.b    256
  19.     endr
  20.             
  21. proc    Main
  22.  
  23. ; function FastFind(p:ptr) : longInt;
  24.  
  25. Export    FUNCTION    FastFind(p:L):L
  26.     VAR    wi:W, oe:W, pb:$40
  27.     BEGIN    SAVE=D3-D7/A2-A4,WITH=(findRecord)
  28.  
  29. ; p = A4
  30. ; datap = a2
  31. ; data_index = D7
  32. ; word_index = D6
  33. ; count = d5
  34. ; amount = ch = d4 (local, temporary)
  35. ; length(word) = d3
  36.  
  37.     move.l    p(a6),a4
  38.     move.l    datap(a4),a2
  39.     move.l    di(a4),d7
  40.     move.l    count(a4),d5
  41.     clr.l    d3
  42.     move.b    word(a4),d3
  43.     
  44. ;   oe := noErr;
  45.     move.w    #0,oe(a6)
  46. ;   wi := length(word);
  47.     move.l    d3,d6
  48.     
  49. ;   while (oe = noErr) and (wi <> 0) and (pos + data_index < filelen) do begin
  50. loop
  51.     tst.w    oe(a6)
  52.     bne    while_exit
  53.     tst.l    d6
  54.     beq    while_exit
  55.     move.l    pos(a4),d0
  56.     add.l    d7,d0
  57.     move.l    filelen(a4),d1
  58.     cmp.l    d0,d1
  59.     bls    while_exit
  60.     
  61. ;    if data_index > count then begin
  62.     cmp.l    d7,d5
  63.     bhs.s    if_end
  64.     
  65. ;     amount := count - data_index + length(word);
  66.     move.l    d5,d4
  67.     sub.l    d7,d4
  68.     add.l    d3,d4
  69.     
  70. ;     pos := pos + count - amount;
  71.     move.l    d5,d0
  72.     sub.l    d4,d0
  73.     add.l    d0,pos(a4)
  74.  
  75. ;    BlockMove(@datap^[data_index - length(word) + 1], ptr(datap), amount);
  76.     move.l    a2,a0
  77.     add.l    d7,a0
  78.     add.l    d3,a0
  79. ;    add.l    #1,a0
  80. ;    sub.l    #1,a0            ; base of datap^ is 1
  81.     move.l    a2,a1
  82.     move.l    d4,d0
  83.     sub.l    #1,d0
  84.     bmi.s    block_move_exit
  85. block_move
  86.     move.b    (a0)+,(a1)+
  87.     dbf    d0,block_move
  88. block_move_exit
  89.  
  90. ;     data_index := length(word);
  91.     move.l    d3,d7
  92.     
  93. ;     count := size - amount;
  94.     move.l    size(a4),d5
  95.     sub.l    d4,d5
  96.     
  97. ;     oe := FSRead(rn, count, @datap^[amount + 1]);
  98. ;     if oe=eofErr then oe:=noErr;
  99.     lea    pb(a6),a0
  100.     move.l    a1,$20(a0)
  101.     move.w    rn(a4),$18(a0)
  102.     move.l    d5,$24(a0)
  103.     clr.w    $2c(a0)
  104.     clr.l    $2e(a0)
  105.     dc.w    $A002            ; _Read
  106.     cmp.w    #-39,d0
  107.     bne.s    @5
  108.     clr.w    d0
  109. @5    move.w    d0,oe(a6)
  110.     move.l    $28(a0),d5
  111.  
  112. ;     count := count + amount;
  113.      add.l    d4,d5
  114.  
  115. ;   end;
  116. if_end
  117.  
  118. ;    if (data_index > count) and (oe = noErr) then
  119. ;     oe := -1;
  120.      move.w    oe(a6),d0
  121.     cmp.l    d7,d5
  122.     bhs.s    no_err
  123.     tst.w    d0
  124.     bne.s    no_err
  125.     move.w    #-1,d0
  126.     move.w    d0,oe(a6)
  127. no_err
  128.  
  129. ;if oe = noErr then begin
  130.     tst.w    d0
  131.     bne.s    give_up
  132.  
  133.     lea    -1(a2,d7.l),a0
  134.     lea    word(a4),a1
  135.     lea    (a1,d3.w),a3
  136.     lea    (a1,d6.w),a1
  137.     move.l    d3,d0        ; d0 = length(word) - wi + 1
  138.     sub.w    d6,d0
  139.     add.w    #1,d0
  140.     clr.w    d4
  141.     clr.l    d1
  142. ;  repeat
  143. ;    ch := UpCase(datap^[data_index]);
  144. ;    if ch = word[wi] then begin
  145. ;      data_index := data_index - 1;
  146. ;      wi := wi - 1;
  147. ;      if wi=0 then leave;
  148. ;    end else begin
  149. ;      data_index := data_index + max(length(word) - wi + 1, skip[ch]);
  150. ;      wi := length(word);
  151. ;      if data_index>count then leave
  152. ;    end;
  153. ;  until false
  154.  
  155. inner_loop
  156.     move.b    (a0),d4
  157.     cmp.b    #'a',d4
  158.     bcs.s    @1
  159.     cmp.b    #'z'+1,d4
  160.     bcc.s    @1
  161.     sub.b    #$20,d4
  162. @1
  163.     cmp.b    (a1),d4
  164.     beq.s    match
  165.  
  166.     move.b    skip(a4,d4.w),d1
  167.     cmp.w    d0,d1
  168.     bge.s    @2
  169.     move.l    d0,d1
  170. @2    add.l    d1,d7
  171.     add.l    d1,a0
  172.  
  173.     move.l    d3,d6
  174.     move.l    #1,d0
  175.     move.l    a3,a1
  176.     
  177.     cmp.l    d7,d5
  178.     bhs.s    inner_loop
  179.     bra.s    end_inner_loop
  180.  
  181. match
  182.     sub.l    #1,d7
  183.     sub.l    #1,a0
  184.  
  185.     sub.l    #1,a1
  186.     add.l    #1,d0
  187.     sub.w    #1,d6
  188.     bne.s    inner_loop
  189.     
  190. end_inner_loop
  191.  
  192. ;   end;
  193. give_up
  194.  
  195. ;  end;
  196.     bra.s    loop
  197. while_exit
  198.  
  199. ;   if wi <>0 then begin
  200.     tst.w    d6
  201.     beq.s    yeah
  202.     
  203. ;    if oe >= 0 then
  204. ;     oe := -1;
  205. ;    Find := oe;
  206.     move.w    oe(a6),d0
  207.     ext.w    d0
  208.     tst.l    d0
  209.     bmi.s    @3
  210.     move.l    #-1,d0
  211. @3
  212. ;   end
  213.     bra.s    yeah_end
  214. ;   else begin
  215. yeah
  216. ;    data_index := data_index + 1;
  217.     add.l    #1,d7
  218. ;    Find := pos + data_index;
  219.     move.l    pos(a4),d0
  220.     add.l    d7,d0
  221.     
  222. ;    data_index := data_index + length(word);
  223.     add.l    d3,d7
  224.  
  225. ;   end;
  226. yeah_end
  227.  
  228.     move.l    d7,di(a4)
  229.     move.l    d5,count(a4)
  230.  
  231.     RETURN    D0
  232.     
  233.     ENDP
  234.  
  235.     END
  236.     
  237.     
  238.     
  239. asm -wb "{active}" -i "{MPW}AStructMacs"
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251. Max
  252.     move.l    (sp)+,d0
  253.     move.l    (sp)+,d1
  254.     cmp.l    d0,d1
  255.     bge    @4
  256.     move.l    d0,d1
  257. @4    move.l    d1,(sp)
  258.     rts
  259.  
  260.  
  261.  
  262. Find    link    a6,
  263.     
  264.     
  265. ; inline function UpCase(ch:char) : char;
  266.     move.w    (sp)+,d0
  267.     cmp.b    #'a',d0
  268.     bcs    @1
  269.     cmp.b    #'z'+1,d0
  270.     bcc    @1
  271.     sub.b    #$20,d0
  272. @1    move.w    d0,(sp)
  273.     rts
  274.     
  275. cd "{MPW}AStructMacs"
  276.  
  277. files "{MPW}AStructMacs"
  278. FlowCtlMacs.a
  279. Instructions
  280. ProgStrucMacs.a
  281. Sample.a
  282. Sample.make
  283. Sample.r
  284.  
  285.  
  286.  type
  287.   dataArray = packed array[1..1000000] of char;
  288.   wordType = str63;
  289.   findRecord = record
  290.     size: longInt;
  291.     datap: ^dataArray;
  292.     word: wordType;
  293.     rn: integer;
  294.     filelen, pos, count, data_index: longInt;
  295.     skip: packed array[char] of byte;
  296.     data: integer;
  297.    end;
  298.   findPtr = ^findRecord;
  299.  
  300.  function Find (p: ptr): longInt;
  301.   var
  302.    oe: OSErr;
  303.    amount: 0..63;
  304.    ch: char;
  305.    wi: integer;
  306.  begin
  307.   with findPtr(p)^ do begin
  308.    oe := noErr;
  309.    wi := length(word);
  310.    while (oe = noErr) and (wi >= 1) and (pos + data_index < filelen) do begin
  311. { data_index is the last character in data that we are checking now }
  312.  
  313.     if data_index > count then begin
  314.      amount := count - (data_index - length(word));
  315.      pos := pos + count - amount;
  316.      BlockMove(@datap^[data_index - length(word) + 1], ptr(datap), amount);
  317.      data_index := length(word);
  318.      count := size - amount;
  319.      oe := FSRead(rn, count, @datap^[amount + 1]);
  320.      count := count + amount;
  321.     end;
  322.     if (data_index > count) and (oe = noErr) then
  323.      oe := -1;
  324.     if oe = noErr then begin
  325.      while (data_index <= count) and (wi >= 1) do begin
  326.       ch := UpCase(datap^[data_index]);
  327.       if ch = word[wi] then begin
  328.        data_index := data_index - 1;
  329.        wi := wi - 1;
  330.       end
  331.       else begin
  332.        if length(word) - wi + 1 > skip[ch] then
  333.        data_index := data_index + length(word) - wi + 1
  334.        else
  335.        data_index := data_index + skip[ch];
  336.        wi := length(word);
  337.       end;
  338.      end;
  339.     end;
  340.    end;
  341.    if wi >= 1 then begin
  342.     if oe >= 0 then
  343.      oe := -1;
  344.     Find := oe;
  345.    end
  346.    else begin
  347.     Find := pos + data_index + 1;
  348.     data_index := data_index + length(word) + 1;
  349.    end;
  350.   end;
  351.  end;
  352.